﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml.Linq;
using LogLib;
using System.Xml;

namespace PhotoUploader
{
    /// <summary>
    /// 接口动态库配置
    /// </summary>
    public class InterfaceConfig
    {
        public int ID { get; set; }
        public string Directory { get; set; }
        public string DllName { get; set; }
        public string TypeName { get; set; }      
        public string InterfaceName { get; set; }
        public string ChineseDescrtiption { get; set; }
        public bool Enable { get; set; }
        public int Timeout { get; set; }
    }

    public class InterfaceConfigReader<T> where T : new()
    {
        private string _error = "";
        public string ErrorMessage
        {
            get
            {
                return _error;
            }
        }

        private string _file = "";

        public List<T> ListInterfaces = new List<T>();

        public InterfaceConfigReader(string file)
        {
            _file = file;
        }

        public bool Load()
        {
            ListInterfaces.Clear();
            if (!File.Exists(_file))
            {
                _error = "找不到配置文件: " + _file;
                return false;
            }
            XDocument xmlDoc = XDocument.Load(_file);
            XElement root = xmlDoc.Element("Interfaces");
            if (root == null)
            {
                _error = "加载接口配置文件错误: 找不到根节点Interfaces";
                return false;
            }
           
            IEnumerable<XElement> elems = root.Elements("Interface");
            if (elems == null)
            {
                _error = "加载接口配置文件错误: 找不到配置节点Interface";
                return false;
            }
                
            if (elems.Count() == 0)
            {
                _error = "加载接口配置文件错误: 配置节点Interface数量=0";
                return false;
            }         
            PropertyInfo propertyInfo = null;
            try
            {
                Type type = typeof(T);
                foreach (XElement e in elems)
                {
                    T temp = new T();
                    IEnumerable<XAttribute> atts = e.Attributes();
                    foreach (XAttribute att in atts)
                    {
                        string name = att.Name.ToString();
                        string value = att.Value.Trim();
                        propertyInfo = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public);
                        if (propertyInfo != null)
                        {
                            if (propertyInfo.PropertyType == typeof(bool) || propertyInfo.PropertyType == typeof(System.Boolean))
                            {
                                propertyInfo.SetValue(temp, ConvertToBoolean(value, true), null); //给对应属性赋值
                            }
                            else if (propertyInfo.PropertyType == typeof(int))
                            {
                                propertyInfo.SetValue(temp, ConvertToInt32(value, 120), null); //给对应属性赋值
                            }
                            else
                            {
                                propertyInfo.SetValue(temp, value, null); //给对应属性赋值
                            }
                        }
                        else
                        {

                        }
                    }
                    ListInterfaces.Add(temp);
                }
                return true;
            }
            catch (System.Exception ex)
            {
                _error = "加载配置文件发生了异常:" + ex.Message;
                return false;
            }
        }

   
        public bool AddConfig(T t)
        {
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(_file);
                XmlElement root = xmlDoc["Interfaces"];
                Type type = typeof(T);
                XmlElement elem = xmlDoc.CreateElement("Interface");
                PropertyInfo[] Properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
                foreach (PropertyInfo p in Properties)
                {
                    string name = p.Name;
                    object oVal = p.GetValue(t, null);
                    if (oVal == null)
                    {
                        elem.SetAttribute(name, "");
                        continue;
                    }
                    string value = oVal.ToString();
                    if (!string.IsNullOrEmpty(value))
                    {
                        elem.SetAttribute(name, value);
                    }
                    else
                    {
                        elem.SetAttribute(name, "");
                    }
                }
                root.AppendChild(elem);
                xmlDoc.Save(_file);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public bool UpdateConfigs(List<T> listConfigs)
        {
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(_file);
                XmlElement root = xmlDoc["Interfaces"];
                root.RemoveAll();
                Type type = typeof(T);                           
                foreach (T t in listConfigs)
                {
                    PropertyInfo[] Properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
                    XmlElement elem = xmlDoc.CreateElement("Interface");
                    foreach (PropertyInfo p in Properties)
                    {
                        string name = p.Name;
                        object oVal = p.GetValue(t, null);
                        if (oVal == null)
                        {
                            elem.SetAttribute(name, "");
                            continue;
                        }
                        string value = oVal.ToString();
                        if (!string.IsNullOrEmpty(value))
                        {
                            elem.SetAttribute(name, value);
                        }
                        else
                        {
                            elem.SetAttribute(name, "");
                        }
                    }
                    root.AppendChild(elem);
                }                
                xmlDoc.Save(_file);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public static bool ConvertToBoolean(string tStr, bool defaultVal = true)
        {
            if (string.IsNullOrEmpty(tStr))
            {
                return defaultVal;
            }
            bool value = defaultVal;
            bool.TryParse(tStr, out value);
            return value;
        }

        public static int ConvertToInt32(string tStr, int defaultVal = 120)
        {
            if (string.IsNullOrEmpty(tStr))
            {
                return defaultVal;
            }
            int value = defaultVal;
            int.TryParse(tStr, out value);
            return value;
        }
    }
}
